/*
 * Copyright (c) 2008, Xiong Yingfei, the University of Tokyo
 * All rights reserved.
 */
package ac.jp.u_tokyo.SyncLib.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;

public class StringHelper
{

	public static String getJavaString(String v) {
		return '\"' + escapeJavaStyleString(v, false) + '\"';
	}

	/**
	 * <p>Escapes and unescapes <code>String</code>s for
	 * Java, Java Script, HTML, XML, and SQL.</p>
	 *
	 * @author Apache Jakarta Turbine
	 * @author GenerationJavaCore library
	 * @author Purple Technology
	 * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
	 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
	 * @author <a href="mailto:cybertiger@cyberiantiger.org">Antony Riley</a>
	 * @author Helge Tesgaard
	 * @author <a href="sean@boohai.com">Sean Brown</a>
	 * @author <a href="mailto:ggregory@seagullsw.com">Gary Gregory</a>
	 * @author Phil Steitz
	 * @author Pete Gieser
	 * @since 2.0
	 * @version $Id: StringEscapeUtils.java,v 1.25 2003/08/18 02:22:23 bayard Exp $
	 */
	public static String escapeJavaStyleString(String str, boolean escapeSingleQuotes) {
	    if (str == null) {
	        return null;
	    }
	    try {
	        StringPrintWriter writer = new StringPrintWriter(str.length() * 2);
	        escapeJavaStyleString(writer, str, escapeSingleQuotes);
	        return writer.getString();
	    } catch (IOException ioe) {
	        // this should never ever happen while writing to a StringWriter
	        ioe.printStackTrace();
	        return null;
	    }
	}

	private static void escapeJavaStyleString(Writer out, String str, boolean escapeSingleQuote) throws IOException {
	    if (out == null) {
	        throw new IllegalArgumentException("The Writer must not be null");
	    }
	    if (str == null) {
	        return;
	    }
	    int sz;
	    sz = str.length();
	    for (int i = 0; i < sz; i++) {
	        char ch = str.charAt(i);
	
	        // handle unicode
	        if (ch > 0xfff) {
	            out.write("\\u" + hex(ch));
	        } else if (ch > 0xff) {
	            out.write("\\u0" + hex(ch));
	        } else if (ch > 0x7f) {
	            out.write("\\u00" + hex(ch));
	        } else if (ch < 32) {
	            switch (ch) {
	                case '\b':
	                    out.write('\\');
	                    out.write('b');
	                    break;
	                case '\n':
	                    out.write('\\');
	                    out.write('n');
	                    break;
	                case '\t':
	                    out.write('\\');
	                    out.write('t');
	                    break;
	                case '\f':
	                    out.write('\\');
	                    out.write('f');
	                    break;
	                case '\r':
	                    out.write('\\');
	                    out.write('r');
	                    break;
	                default :
	                    if (ch > 0xf) {
	                        out.write("\\u00" + hex(ch));
	                    } else {
	                        out.write("\\u000" + hex(ch));
	                    }
	                    break;
	            }
	        } else {
	            switch (ch) {
	                case '\'':
	                    if (escapeSingleQuote) out.write('\\');
	                    out.write('\'');
	                    break;
	                case '"':
	                    out.write('\\');
	                    out.write('"');
	                    break;
	                case '\\':
	                    out.write('\\');
	                    out.write('\\');
	                    break;
	                default :
	                    out.write(ch);
	                    break;
	            }
	        }
	    }
	}

	/**
	 * <p>Returns an upper case hexadecimal <code>String</code> for the given
	 * character.</p>
	 *
	 * @param ch The character to convert.
	 * @return An upper case hexadecimal <code>String</code>
	 */
	public static String hex(char ch) {
	    return Integer.toHexString(ch).toUpperCase();
	}

}

/**
 * <p>A PrintWriter that maintains a String as its backing store.</p>
 *
 * <p>Usage:
 * <pre>
 * StringPrintWriter out = new StringPrintWriter();
 * printTo(out);
 * System.out.println( out.getString() );
 * </pre>
 * </p>
 *
 * @author Alex Chaffee
 * @author Scott Stanchfield
 * @since 2.0
 */
class StringPrintWriter extends PrintWriter {

    public StringPrintWriter() {
        super(new StringWriter());
    }

    public StringPrintWriter(int initialSize) {
        super(new StringWriter(initialSize));
    }

    /**
     * <p>Since toString() returns information *about* this object, we
     * want a separate method to extract just the contents of the
     * internal buffer as a String.</p>
     *
     * @return the contents of the internal string buffer
     */
    public String getString() {
        flush();
        return ((StringWriter) out).toString();
    }

}
